﻿// Contains catalog information and stored procedure wrapper classes.
using System;
using System.Configuration;
using System.Data;

using BizElements.Core;
using BizElements.BusinessLayer;

namespace BizElements.BusinessLayer
{
	/// <summary>
	/// Catalog used by classes in the BizElements.BusinessLayer namespace.
	/// Reads information from *.config file.
	/// </summary>
	[Serializable]
	internal sealed class Catalog : ICatalog
	{
		#region ICatalog.

		private static readonly DbmsType dbmsType;
		private static readonly string connectionString;

		static Catalog()
		{
			string cfgDbmsType = ConfigurationManager.AppSettings["BizElements.BusinessLayer.EntitySecurityProvider.DbmsType"];
			if (cfgDbmsType != null)
				dbmsType = (DbmsType)Enum.Parse(typeof(DbmsType), cfgDbmsType);

			if ((ConfigurationManager.ConnectionStrings != null) && (ConfigurationManager.ConnectionStrings["BizElements.BusinessLayer.EntitySecurityProvider.ConnectionString"] != null))
				connectionString = ConfigurationManager.ConnectionStrings["BizElements.BusinessLayer.EntitySecurityProvider.ConnectionString"].ConnectionString;
		}

		/// <summary>
		/// Gets database type.
		/// </summary>
		public DbmsType DbmsType
		{
			get { return dbmsType; }
		}

		/// <summary>
		/// Gets connection string.
		/// </summary>
		public string ConnectionString
		{
			get { return connectionString; }
		}

		/// <summary>
		/// Creates a connection provider for this catalog.
		/// </summary>
		/// <returns>Connection provider that connects to this catalog.</returns>
		public IConnectionProvider CreateConnectionProvider()
		{
			return ConnectionProviderFactory.CreateConnectionProvider(this.DbmsType, this.ConnectionString);
		}

		#endregion

		#region Configuration - overriden/obfuscated table and column names.

		const string TableNameOverrideKeyFormat = "BizElements.BusinessLayer.{0}.TableName";

		/// <summary>Gets overriden/obfuscated table name from application's configuration file.</summary>
		internal static string GetTableNameOverride(string tableName)
		{
			string settingsKey = string.Format(TableNameOverrideKeyFormat, tableName);
			return ConfigurationManager.AppSettings[settingsKey];
		}

		const string ColumnNameOverrideKeyFormat = "BizElements.BusinessLayer.{0}.{1}.ColumnName";

		/// <summary>Gets overriden/obfuscated column name from application's configuration file.</summary>
		internal static string GetColumnNameOverride(string tableName, string columnName)
		{
			string settingsKey = string.Format(ColumnNameOverrideKeyFormat, tableName, columnName);
			return ConfigurationManager.AppSettings[settingsKey];
		}

		#endregion

		#region GetTextSourceInitializer.

		static TextSourceInitializer EnsureMessageSource;
		static readonly object EnsureMessageSourceSyncRoot = new object();

		/// <summary>Gets delegate to static "BizElements.BusinessLayer.MessageHelper.EnsureInstance" method which is used to initialize message sources for all entities in this assembly.</summary>
		public static TextSourceInitializer GetTextSourceInitializer()
		{
			if (EnsureMessageSource == null)
			{
				lock (EnsureMessageSourceSyncRoot)
				{
					EnsureMessageSource = ReflectionUtil.CreateDelegate<TextSourceInitializer>("BizElements.BusinessLayer", "BizElements.BusinessLayer.MessageHelper", "EnsureInstance");
				}
			}

			return EnsureMessageSource;
		}

		#endregion

	}
}